package com.alan.search.service.impl;

import com.alan.search.dao.BaseElasticDao;
import com.alan.search.entity.OrderBO;
import com.alan.search.entity.OrderSearchDTO;
import com.alan.search.service.OrderService;
import com.alan.search.vo.EsPage;
import com.alan.search.vo.OrderVO;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;

/**
 * @author shiml
 * @date 2021/12/3 3:02 下午
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final BaseElasticDao baseElasticDao;

    final String INDEX_ORDER = "shiml-order";

    @Override
    public EsPage<OrderVO> pageOrder(OrderSearchDTO dto) {

        // 构造查询语句
        SearchRequest searchRequest = this.orderSearch(dto.getCurrent(), dto.getSize(), dto);
        // 执行查询
        EsPage<OrderVO> page = baseElasticDao.search(searchRequest, OrderVO.class);

        return page;
    }

    @Override
    public OrderVO getOrder(Long orderNo) {

        OrderVO result = new OrderVO();

        SearchRequest searchRequest = new SearchRequest(INDEX_ORDER);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("orderNo", orderNo));
        sourceBuilder.query(boolQueryBuilder);
        searchRequest.source(sourceBuilder);
        List<OrderVO> list = baseElasticDao.listSearch(searchRequest, OrderVO.class);
        if (!CollectionUtils.isEmpty(list)) {
            result = list.get(0);
        }

        return result;
    }

    private SearchRequest orderSearch(Integer current, Integer size, OrderSearchDTO dto) {

        log.debug("OrderSearchDTO: [{}]", JSON.toJSONString(dto));

        // 索引集合
        SearchRequest searchRequest = new SearchRequest(INDEX_ORDER);

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 订单编码 & 商品名称
        if (!StringUtils.isEmpty(dto.getContent())) {
            boolQueryBuilder.must(QueryBuilders.multiMatchQuery(dto.getContent(), "orderNo", "goods.goodsName"));
        }
        // 订单状态
        if (null != dto.getStatus()) {
            boolQueryBuilder.must(QueryBuilders.termQuery("status", dto.getStatus()));
        }
        // 订单创建时间
        if (!StringUtils.isEmpty(dto.getCreateTimeRange())) {
            String[] longs = dto.getCreateTimeRange().split("=");
            Long startTimeLong = null;
            Long endTimeLong = null;

            if (null != longs[0]) {
                startTimeLong = Long.valueOf(longs[0]);
            }
            if (null != longs[1]) {
                endTimeLong = Long.valueOf(longs[1]);
            }
            LocalDateTime form = LocalDateTime.ofEpochSecond(startTimeLong, 0, ZoneOffset.ofHours(0));
            LocalDateTime to = LocalDateTime.ofEpochSecond(endTimeLong, 0, ZoneOffset.ofHours(0));
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("createTime").from(form).to(to));
        }

        // todo 其他条件

        sourceBuilder.query(boolQueryBuilder);

        Integer form = (current.intValue() - 1) * size.intValue();
        sourceBuilder.from(form);
        sourceBuilder.size(size);

        // 排序
        sourceBuilder.sort("createTime", SortOrder.DESC);

        log.info("searchLogPage: DSL = \n {}", JSON.toJSONString(sourceBuilder));

        searchRequest.source(sourceBuilder);

        return searchRequest;

    }


}
